package ide.ccf.ccproject;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;


/**
 * 项目文件变化侦听器
 *
 */
public class PorjectFileChangedListener implements IResourceChangeListener 
{
	/**
	 * 资源变化事件处理
	 */
	public void resourceChanged(IResourceChangeEvent event) 
	{
		// 忽略项目的关闭/删除、编译前/编译后事件
		if (event.getType() == IResourceChangeEvent.POST_CHANGE) 
		{
			// 资源改变事件总是在工作空间的根开始，所以项目就在事件的下一级
			IResourceDelta[] projects = event.getDelta().getAffectedChildren();
			
			if (projects.length > 0) 
			{
				for (IResourceDelta projectDelta : projects) 
				{
					if (((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) || projectDelta.getKind() == IResourceDelta.REMOVED) 
					{
						// 如果项目刚刚被创建、打开、重命名、关闭或删除，那么可以忽略这个事件
						continue;
					}
					
					// 忽略标记变化
					if ((projectDelta.getFlags() & IResourceDelta.MARKERS) != 0) 
					{
						continue;
					}
					
					// 忽略描述变化
					if ((projectDelta.getFlags() & IResourceDelta.DESCRIPTION) != 0) 
					{
						continue;
					}

					IResource resource = projectDelta.getResource();
					
					if (resource != null && resource instanceof IProject) 
					{
						// 如果项目不是CCF项目，则忽略这个变化
						final IProject project = (IProject)resource;
						
						try 
						{
							if (project.isAccessible() && project.hasNature(CCFNature.NATURE_ID)) 
							{
								// 检查项目选项
								if (new CCFProject(project).runQMakeWhenProjectFileChanges()) 
								{
									// 访问所有子资源
									boolean runQmake = visitChildren(projectDelta);
									
									if (runQmake) 
									{
										WorkspaceJob runQmakJob = new WorkspaceJob("调用qmake") 
										{
											@SuppressWarnings("unused")
											@Override
											public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException 
											{
												String errStr = "QMakeRunner.runQMake(project, monitor)"; //TODO Mencius
												
												if (errStr != null) 
												{
													return new Status(IStatus.ERROR, ProjectPlugin.PLUGIN_ID, errStr);
												}
												
												return Status.OK_STATUS;
											}
										};
										runQmakJob.setUser(true);
										runQmakJob.setRule(project);
										runQmakJob.schedule();
									}
								}
							}
						} 
						catch (CoreException e) 
						{
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	// 访问子资源
	private boolean visitChildren(IResourceDelta delta) 
	{
		IResourceDelta[] changedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED);
		
		if (changedChildren.length > 0) 
		{
			for (IResourceDelta child : changedChildren) 
			{
				// 忽略标记变化
				if ((child.getFlags() & IResourceDelta.MARKERS) != 0) 
				{
					continue;
				}

				IResource resource = child.getResource();
				
				if (resource != null) 
				{
					if (resource instanceof IFile) 
					{
						String name = resource.getName().toLowerCase();
						
						// TODO 理想情况是我们只监听主pro文件中包含的那些文件的变化事件
						if (name.endsWith(".pro") || name.endsWith(".pri")) 
						{
							return true;
						}
					} 
					else if (resource instanceof IFolder) 
					{
						visitChildren(child);
					}
				}
			}
		}
		return false;
	}
}